var PathFollowAI = function ( ghost , path ) {

	this.ghost = ghost;

	this.path = path;

	this.pathStep = 0;

};

var p = PathFollowAI.prototype;

p.getDirection = function () {

	var ghost = this.ghost;

	var dir = this.path[ this.pathStep++ ];

	if ( dir == "end" ) {

		ghost.AI = new SimpleFollowAI ( ghost );

		ghost.AI.getDirection();

		return;

	}

	ghost.current_dir = dir;

	ghost.getVector();

}

var SimpleFollowAI = function ( ghost ) {

	this.ghost = ghost;

};

var p = SimpleFollowAI.prototype;

p.getDirection = function () {

	var ghost = this.ghost;

	var bitflag = ghost.bitflag;
	var target = ghost.target;

	var rx = ghost._x >> 3;
	var ry = ghost._y >> 3;

	var dx = target._x - ghost._x;
	var dy = target._y - ghost._y;

	if ( ghost.mode == "eye" && dx == 0 && dy == 0 ) {

		ghost.switchToNormalMode();

		ghost.target = ghost.pacMan;

		ghost.AI = new PathFollowAI ( ghost , [ 8 , 8 , "end" ] );

		ghost.AI.getDirection();

		ghost.bitflag = 1;

		return;

	};

	if ( Math.abs( dy ) > Math.abs( dx ) ) {

		if ( dy > 0 ) {

			if ( ~map[ ry + 1 ][ rx ] & bitflag ) {

				ghost.current_dir = 4;

				ghost.getVector();

				return;

			} else {

				if ( dx < 0 && ~map[ ry ][ rx - 1 ] & bitflag ) {

					this.findNextNode( 66 );

					return;

				} else {

					this.findNextNode( 65 );

					return;

				}

			}

		} else {

			if ( ~map[ ry - 1 ][ rx ] & bitflag ) {

				ghost.current_dir = 8;

				ghost.getVector();

				return;

			} else {

				if ( dx < 0 && ~map[ ry ][ rx - 1 ] & bitflag ) {

					this.findNextNode( 130 );

					return;

				} else {

					this.findNextNode( 129 );

					return;

				}

			}

		}

	} else {

		if ( dx < 0 ) {

			if ( ~map[ ry ][ rx - 1 ] & 1 ) {

				ghost.current_dir = 2;

				ghost.getVector();

				return;

			} else {

				if ( dy > 0 && ~map[ ry + 1 ][ rx ] & bitflag ) {

					this.findNextNode( 36 );

					return;

				} else {

					this.findNextNode( 40 );

					return;

				}

			}

		} else {

			if ( ~map[ ry ][ rx + 1 ] & bitflag ) {

				ghost.current_dir = 1;

				ghost.getVector();

				return;

			} else {

				if ( dy > 0 && ~map[ ry + 1 ][ rx ] & bitflag ) {

					this.findNextNode( 20 );

					return;

				} else {

					this.findNextNode( 24 );

					return;

				}

			}

		}

	}

}

p.findNextNode = function ( search_code ) {

	var ghost = this.ghost;

	var bitflag = ghost.bitflag;

	var rx = ghost._x >> 3;
	var ry = ghost._y >> 3;

	var path = [];

	switch ( search_code ) {

		case 65:

			while ( map[ ry + 1 ][ rx++ ] & bitflag ) {

				if ( map[ ry ][ rx ] & bitflag ) { this.findNextNode( 66 ); return; };

				path.push( 1 );

			};

			path.push ( 4 );

			break;

		case 66:

			while ( map[ ry + 1 ][ rx-- ] & bitflag ) {

				if ( map[ ry ][ rx ] & bitflag ) { this.findNextNode( 65 ); return; };

				path.push( 2 );

			};

			path.push ( 4 );

			break;

		case 129:

			while ( map[ ry - 1 ][ rx++ ] & bitflag ) {

				if ( map[ ry ][ rx ] & bitflag ) { this.findNextNode( 130 ); return; };

				path.push( 1 );

			};

			path.push ( 8 );

			break;

		case 130:

			while ( map[ ry - 1 ][ rx-- ] & bitflag ) {

				if ( map[ ry ][ rx ] & bitflag ) { this.findNextNode( 129 ); return; };

				path.push( 2 );

			};

			path.push ( 8 );

			break;

		case 36:

			while ( map[ ry++ ][ rx - 1 ] & bitflag ) {

				if ( map[ ry ][ rx ] & bitflag ) { this.findNextNode( 40 ); return; };

				path.push( 4 );

			};

			path.push( 2 );

			break;

		case 40:

			while ( map[ ry-- ][ rx - 1 ] & bitflag ) {

				if ( map[ ry ][ rx ] & bitflag ) { this.findNextNode( 36 ); return; };

				path.push( 8 );

			};

			path.push( 2 );

			break;

		case 20:

			while ( map[ ry++ ][ rx + 1 ] & bitflag ) {

				if ( map[ ry ][ rx ] & bitflag ) { this.findNextNode( 24 ); return; };

				path.push( 4 );

			};

			path.push( 1 );

			break;

		case 24:

			while ( map[ ry-- ][ rx + 1 ] & bitflag ) {

				if ( map[ ry ][ rx ] & bitflag ) { this.findNextNode( 20 ); return; };

				path.push( 8 );

			};

			path.push( 1 );

			break;

	}

	ghost.vx = ghost.vy = 0;

	path.push( "end" );

	ghost.AI = new PathFollowAI( ghost , path );

}

var RandomAI = function ( ghost ) {

	this.ghost = ghost;

}

var p = RandomAI.prototype;

p.getDirection = function () {

	var ghost = this.ghost;

	var bitflag = ghost.bitflag;

	var rx = ghost._x >> 3;
	var ry = ghost._y >> 3;

	var lastDir = ghost.current_dir;

	var possible = [];

	if ( ~map[ ry ][ rx + 1 ] & bitflag && lastDir != 2 ) possible.push ( 1 );
	if ( ~map[ ry ][ rx - 1 ] & bitflag && lastDir != 1 ) possible.push ( 2 );
	if ( ~map[ ry + 1 ][ rx ] & bitflag && lastDir != 8 ) possible.push ( 4 );
	if ( ~map[ ry - 1 ][ rx ] & bitflag && lastDir != 4 ) possible.push ( 8 );

	var dir = possible[ random( possible.length ) ];

	ghost.current_dir = dir;

	ghost.getVector();

}
























